/*=============================================================================

  DIO INTERFACE MODULE

  FILE: HIO.cpp
  
  DESCRIPTION

    DIO Interface MOudle

  Copyright (c) DaeSung Engineering Inc. All rights reserved.

=============================================================================*/
/*=============================================================================

                             EDIT HISTORY

  ---------  -------  -------------------------------------------------------
    when       who     what, where, why
  ---------  -------  -------------------------------------------------------
   08/10/03   nso4th   Initial version

=============================================================================*/

/*=============================================================================
  HEADER INCLUSION
=============================================================================*/
#include "HIO.h"
#include <devSP/ioHal_emul.h>

/*=============================================================================
  CONSTANT DEFINIION
=============================================================================*/
/*=============================================================================
  LOCALIZED FUNCTIONS
=============================================================================*/
static dword ioEventCallback(dword dwEvent, dword wParam, dword lParam, mcxt pUser);

/*=============================================================================
  CONSTRCUTOR & DESTRUCTOR
=============================================================================*/
HIO::HIO():HIOBase()
{
	Event_SetCallback(ioEventCallback, this);
}

HIO::~HIO()
{
	Close();
}

/*=============================================================================
  OPERATION
=============================================================================*/
/* Initialize */
boolean HIO::Init(char *pszName)
{
	int32		i, n;
	dword		devName, devID;
	iodev_setup_s		*tbl;
	
	if(HIOBase::Init(pszName) == FALSE)
		return	FALSE;

	n = m_pCFG->dev_num;
	for(i=0; i<n; i++)
	{
		SetCurrentDevice(i);

		DioDev_DeviceID(m_pDev, &devName, &devID);

		tbl = m_pCFG->tbl + i;
		if(devName == DIODEV_EMULATOR)
		{
			DioDev_SetParam(m_pDev, DIO_IN_CHAN_NUM_P, tbl->numIn, 0);
			DioDev_SetParam(m_pDev, DIO_OUT_CHAN_NUM_P, tbl->numOut, 0);
		}
		if(devName == DIODEV_AXT_QI)
		{

		}
	}
	SetCurrentDevice(0);

	return	TRUE;
}

/* Close */
boolean	HIO::Close(void)
{
	return	HIOBase::Close();
}

boolean HIO::Connect(void)
{
	iodev_cfg_s			*cfg = m_pCFG;
	iodev_setup_s				*s;
	int32				i;
	ObjClient_s			c;
	int32				cnt;

	if(cfg == NULL)
		return	FALSE;

	if(IsDeviceAvail() == TRUE)
	{
		Disconnect();

		Task_Delay(100);
	}
	
	for(cnt = 0, i=0; i<cfg->dev_num; i++)
	{
		s = cfg->tbl + i;

		m_CliCxt[i].pThis = this;
		m_CliCxt[i].dwDevID = i;
		c.pUserCxt = &m_CliCxt[i];
		c.EventCbf = m_pEvtCb;

		SetCurrentDevice(i);
 		m_pDevList[i] = DioDev_Alloc(&c, (s->dev_name + s->subID));
		if(m_pDevList[i] == NULL)
		{
			m_pDev = NULL;
			
			continue;
		}

		if(!DioDev_Init(m_pDevList[i], s->dev_str))
		{
			DioDev_Free(m_pDevList[i]);
			m_pDevList[i] = NULL;
			m_pDev = NULL;
			
			continue;
		}
		cnt++;
	}
	if(cnt != cfg->dev_num)
	{
		//Close();
		return	FALSE;
	}
	SetCurrentDevice(0);
	
	return	TRUE;
}

boolean HIO::Disconnect(void)
{
	int32		i;

	for(i=0; i<HDEV_MAX; i++)
	{
		if(m_pDevList[i] != NULL)
		{
			DioDev_Execute(m_pDevList[i], DIO_CLOSE_C, 0, 0);
			DioDev_Free(m_pDevList[i]);
			
			m_pDevList[i] = NULL;
		}
	}
	m_pDev = NULL;

	return	TRUE;
}

	
// Model & SN
dword HIO::Model_ID(void)
{
	dword	devName, devID;
	
	if(m_pDev == NULL)
	{
		return	DIODEV_DUMMY;
	}

	if(DioDev_DeviceID(m_pDev, &devName, &devID) == TRUE)
	{
		return	(dword)(devName | devID);
	}

	return	DIODEV_DUMMY;
}

boolean HIO::Model_Name(char *pszMod, int32 szLen)
{
	dword	devName, devID;
	
	if(m_pDev == NULL)
	{
		return	(FALSE);
	}
	if((pszMod == NULL) || (szLen < 20))
	{
		return	FALSE;
	}

	if(DioDev_DeviceID(m_pDev, &devName, &devID) == FALSE)
	{
		return	FALSE;
	}

	switch(devName)
	{
	case DIODEV_AXT_SIO:
	{
		sprintf(pszMod, "AjinXTek SIO (%d)", devID);
		break;
	}
	case DIODEV_AXT_QI:
	{
		sprintf(pszMod, "AjinXTek QI (%d)", devID);
		break;
	}
	case DIODEV_NAIS_SIO:
	{
		sprintf(pszMod, "NAIS PLC (%d)", devID);
		break;
	}
	case DIODEV_ADAM5KTCP_SIO:
	{
		sprintf(pszMod, "ADAM-5000/TCP (%d)", devID);
		break;
	}
	case DIODEV_ADAM6KTCP_SIO:
	{
		sprintf(pszMod, "ADAM-6000/TCP (%d)", devID);
		break;
	}
	case DIODEV_EMULATOR:
	{
		sprintf(pszMod, "Emulator (%d)", devID);
		break;
	}
	default:
		return	FALSE;
	}

	return	TRUE;
}

iodev_cfg_s *HIO::CFG_Get(void)
{
	return	m_pCFG;
}

/*=============================================================================
  APPLICATION IMPLEMENTATION
=============================================================================*/
void HIO::INIT_IO_STATE(void)
{
	/*		----------------------2013. 10. 21. jyko
	// Signal tower
	Output(IO_SIG_RED_OUT, FALSE);
	Output(IO_SIG_GREEN_OUT, FALSE);
	Output(IO_SIG_YELLOW_OUT, FALSE);
	
	// Buzzer
	Output(IO_BUZZER_OUT, FALSE);

	// Reset LED
	Output(IO_RESET_LED_OUT, FALSE);
	*/
}

boolean HIO::Output(dword dwChan, boolean bOn)
{
	int32			j;
	boolean			done;

	if(IsDeviceAvail() == FALSE)
		return	FALSE;
	
	for(j=0; j<10; j++)
	{
		done = HIOBase::Output(dwChan, bOn);
		if(done == TRUE)
		{
			break;
		}
		else
		{
			Task_Delay(10);
			Task_Switch();
		}
	}
	if(done == FALSE)
	{
		//LOGERR("[HIO:Output] Error (%d)", dwChan);
	}
	return	done;
}
boolean HIO::InputSet(dword dwBlock, dword dwIn)
{
	dword		modID = Model_ID();

	modID = modID & 0xFFFFFF00;

	switch(modID)
	{
	case DIODEV_EMULATOR:
	{
		return	(boolean)DioDev_Execute(m_pDev, DIO_EMUL_INPUT_SET_C, dwBlock, dwIn);
	}
	}
	return	FALSE;
}

boolean HIO::InputBitSet(dword dwChan, boolean bOn)
{
	dword		modID = Model_ID();

	modID = modID & 0xFFFFFF00;

	switch(modID)
	{
	case DIODEV_EMULATOR:
	{
		int32		j;
		boolean		done = FALSE;

		for(j=0; j<10; j++)
		{
			done = (boolean)DioDev_Execute(m_pDev, DIO_EMUL_INPUTBIT_SET_C, dwChan, bOn);
			if(done == TRUE)
			{
				break;
			}
			Task_Delay(10);
			Task_Switch();
		}
		if(done == FALSE)
		{
			//LOGERR("[HIO:InputBitSet] Error (%d)", dwChan);
		}
		else
		{
			Task_Delay(10);
			return	TRUE;
		}
	}
	}
	return	FALSE;
}

/*=============================================================================
  EVENT HANDLER
=============================================================================*/
dword HIO::Event_Handler(dword dwEvent, dword wParam, dword lParam)
{
	if(Event_PreProc(HDEV_GETEVENT(dwEvent), wParam, lParam))
	{
		return	TRUE;
	}

	return	Event_Pass(HDEV_GETEVENT(dwEvent), wParam, lParam);
}

dword HIO::Event_PreProc(dword dwEvent, dword wParam, dword lParam)
{
	return	FALSE;
}

static dword ioEventCallback(dword dwEvent, dword wParam, dword lParam, mcxt pUser)
{
	HDevCliCxt	*pCxt = (HDevCliCxt*)pUser;

	if(pCxt && pCxt->pThis)
	{
		return pCxt->pThis->Event_Handler(HDEV_SETDEV_ID(dwEvent, pCxt->dwDevID), wParam, lParam);
	}

	return	(0);
}
/*--- END OF HIO.CPP ---*/
